package com.taotao.common.jackson.mask;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.Objects;

/**
 * 字段打码序列化器
 */
@Slf4j
@AllArgsConstructor
@NoArgsConstructor
class MaskFieldSerializer extends JsonSerializer<Object> implements ContextualSerializer {

    private MaskField maskField;

    @Override
    public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
            throws IOException {

        if (null == value) {
            jgen.writeObject(value);
        }

        String s = value.toString();
        if (Objects.equals(s, "")) {
            return;
        }

        int bi = maskField.beginIndex();
        int ei = maskField.endIndex();
        char mc = maskField.maskChar();

        if (bi < 0) {
            bi = 0;
        }

        int len = s.length();
        if (ei > len) {
            ei = len;
        }

        if (bi > len - 1 || bi >= ei) {
            return;
        }


        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < len; i++) {
            if (i >= bi && i < ei) {
                sb.append(mc);
            } else {
                sb.append(s.charAt(i));
            }
        }

        jgen.writeString(sb.toString());
    }


    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty == null) {
            //为空直接跳过
            return serializerProvider.findNullValueSerializer(beanProperty);
        }

        MaskField anno = beanProperty.getAnnotation(MaskField.class);
        if (null == anno) {
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }

        return new MaskFieldSerializer(anno);
    }
}